/**
 * Copyright 2010 Creative Works, Inc.
 * Creative Works licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.sendvox.freswitch.outbound.impl;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.sendvox.freswitch.core.impl.AbstractChannelHandler;
import org.sendvox.freswitch.event.ChannelDataMessage;
import org.sendvox.freswitch.event.Event;
import org.sendvox.freswitch.event.impl.Header;
import org.sendvox.freswitch.event.impl.MessageFactory;
import org.sendvox.freswitch.event.impl.RawMessage;
import org.sendvox.freswitch.inbound.impl.ResponseCallbacks;

public class OutboundChannelHandler extends AbstractChannelHandler implements
		Closeable {

	private static final Logger logger = Logger
			.getLogger(OutboundChannelHandler.class.getName());

	public final AtomicBoolean isConnnected = new AtomicBoolean(false);

	public OutboundChannelHandler() {
	}

	protected void handleConnectResponse(ChannelHandlerContext ctx,
			RawMessage response) {
		System.out.println("OutboundChannelHandler.handleConnectResponse()");
	}

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		logger.log(Level.INFO,
				"Stablishing connection with FreeSwitch server...");

		RawMessage rawMsg = executeSyncCommand(ctx.getChannel(), "connect");

		handleConnectResponse(ctx, rawMsg);

	}

	@Override
	protected void handleEventSocketMessage(ChannelHandlerContext ctx,
			RawMessage response) {

		final String contentType = response.getContentType();
		if (contentType != null
				&& !response.getHeaders().isEmpty()
				&& contentType.equals(ResponseCallbacks.Value.COMMAND_REPLY
						.getLiteral())) {
			String eventName = response.getEventBodyMap()
					.get(Header.EVENT_NAME);
			if (eventName != null) {
				Event eventType = Event.fromLiteral(eventName);
				switch (eventType) {
				case CHANNEL_DATA:
					System.out
							.println("OutboundChannelHandler.handleEventSocketMessage()");
					ChannelDataMessage channelDataMsg = MessageFactory.INSTANCE
							.createChannelDataMessage(ctx, response);
					dispatcher.fire(channelDataMsg);
					break;
				}
			}
		}

	}

	@Override
	public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		logger.log(Level.INFO,
				"Sendvox FreeSwitch server is officially open for business...");
		super.channelOpen(ctx, e);
	}

	public void close() throws IOException {
		// TODO
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
		// Close the connection when an exception is raised.
		logger.log(Level.WARNING, "Unexpected exception from downstream.",
				e.getCause());
		e.getChannel().close();
	}

}
